home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
general
/
raytrace
/
rayshade
/
graphtal.lzh
/
Graphtal.Amiga
/
Hull.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-17
|
3KB
|
120 lines
/*
* Hull.C - methods for hull manipulations.
*
* Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
* University of Berne, Switzerland
* All rights reserved.
*
* This software may be freely copied, modified, and redistributed
* provided that this copyright notice is preserved on all copies.
*
* You may not distribute this software, in whole or in part, as part of
* any commercial product without the express consent of the authors.
*
* There is no warranty or other guarantee of fitness of this software
* for any purpose. It is provided solely "as is".
*
*/
#include <values.h>
#include "Hull.h"
//___________________________________________________________ Hull
implementTable(HullSymtab, rcString, HullPtr);
Hull::Hull()
: primitives(new GeoObjectList(10))
{}
Hull::~Hull()
{
#ifndef OLD_STYLE_CPP
// AT&T 2.x has problems: too compilcated pointer expression
for (register long i=0; i<primitives->count(); i++)
delete primitives->item(i);
#endif
delete primitives;
}
void Hull::addPrimitive(GeoObject* obj)
{
primitives->append(obj);
}
long Hull::numPrimitives() const
{
return primitives->count();
}
/*
* Intersect ray with hull primitives and calculate closest object
* and distance to this object.
* intersect return TRUE if hit occured, FALSE otherwise.
*/
int Hull::intersect(const Ray& ray, real& dist, GeoObject*& obj) const
{
int hit = FALSE;
TransMatrix* itrans;
dist = MAXFLOAT;
obj = NULL;
for (register long i=0; i<primitives->count(); i++) {
/*
* primitive has transformation matrix attached
* -> transform the ray
*/
if ((itrans = primitives->item(i)->getInvTrans()) != NULL) {
Ray newRay(ray);
real distfact = newRay.transform(*itrans);
/*
* Transformimg the ray can change the distance between the
* ray origin and the Point of intersection. We save the amount
* the is "stretched" and later devide the computed distance
* by this amount.
*/
dist *= distfact;
if (primitives->item(i)->intersect(newRay, EPSILON*distfact, dist)) {
obj = primitives->item(i);
hit = TRUE;
}
dist /= distfact;
}
else {
if (primitives->item(i)->intersect(ray, EPSILON, dist)) {
obj = primitives->item(i);
hit = TRUE;
}
}
}
return hit;
}
/*
* convertToPolygonList tesselates all the primitives in the hull
* and returns the result as a list of polygons.
* If there is no polygon in the hull, a empty polygon list is
* returned.
*/
PolygonList* Hull::convertToPolygonList(const BoundingBox& bbox) const
{
PolygonList* polys = new PolygonList;
PolygonList* polytmp;
for (register long i=0; i<primitives->count(); i++) {
if ((polytmp = primitives->item(i)->tesselate(bbox)) != NULL) {
for (register long j=0; j<polytmp->count(); j++)
polys->append(polytmp->item(j));
delete polytmp;
}
}
return polys;
}